import { LogType, saveLog } from "../utils/LogUtil";
import { getValue } from "../utils/utls";
import { getSpecialMonManage } from "../系统功能/GlobalObjectManage";
import { ClearMonList, ClearMonTime, isClearMon } from "../配置/刷怪";
import { CampEnum, Minute, ActorNkeyEnum } from "../配置/基础配置";

export interface FreshMonCallBack {
    (list: TActorList): void;
}
export class FreshItem {
    name: string;
    x: number;
    y: number;
    range: number;
    num: number;
    interval: number;
    //上次清理的数量
    lastClearNum: number;
    //上次刷新时间
    lastFreshTime: number;

    constructor(itemSet) {
        this.name = itemSet.name;
        this.x = itemSet.x;
        this.y = itemSet.y;
        this.range = itemSet.range;
        this.num = itemSet.num;
        this.interval = itemSet.interval;
        this.lastClearNum = 0;

        this.lastFreshTime = 0;
    }
}

export class FreshMapData {
    mapId: string;
    mapName: string;
    isClear: boolean;
    x: number;
    y: number;
    range: number;
    monList: Array<FreshItem>;

    //上次清理时间
    lastClearTime: number;
    //上次离开时间
    lastLeaveTime: number;


    constructor(itemSet, map: TEnvirnoment) {
        this.mapId = itemSet.mapId;
        this.mapName = map.Name;
        let width = map.MapWidth;
        let height = map.MapHeight;
        this.x = width / 2;
        this.y = height / 2;
        this.range = Math.max(this.x, this.y);

        this.lastClearTime = 0;

        this.lastLeaveTime = 0;
        this.isClear = getValue(itemSet.isClear, isClearMon);

        this.monList = new Array<FreshItem>();
        for (let i = 0; i < itemSet.monList.length; i++) {
            let item = itemSet.monList[i];
            let freshItem = new FreshItem(item);

            freshItem.x = getValue(freshItem.x, this.x)
            freshItem.y = getValue(freshItem.y, this.y)
            freshItem.range = getValue(freshItem.range, this.range)
            freshItem.lastClearNum = 0;
            if (freshItem.interval < 1) {
                freshItem.interval = 1;
            }

            this.monList.push(freshItem);
        }
    }
}

//循环刷怪5次
const loopNum = 5;

export class FreshMon {
    monGenSet: Array<FreshMapData>;
    monGenMap: Map<string, FreshMapData>;
    isFresh: boolean = false;

    constructor(monGenSet: Array<any>) {
        this.initMonGenSet(monGenSet);
    }

    //初始化刷怪列表
    initMonGenSet(monGenSet: Array<any>): void {
        this.monGenSet = new Array<FreshMapData>();
        this.monGenMap = new Map<string, FreshMapData>();
        for (let i = 0; i < monGenSet.length; i++) {
            let item = monGenSet[i];
            let map: TEnvirnoment = GameLib.FindMap(item.mapId)
            if (map) {
                let freshMap: FreshMapData = new FreshMapData(item, map);
                this.monGenSet.push(freshMap);
                this.monGenMap.set(item.mapId, freshMap);
            }
            else {
                saveLog(`${item.mapName}刷怪配置地图不存在`, LogType.FreshMon)
            }
        }
    }

    //人员离开地图 
    HumanLeave(map: TEnvirnoment) {
        let count = map.HumCount;
        if (count == 0) {
            let item = this.monGenMap.get(map.MapID);
            if (item) {
                item.lastLeaveTime = GameLib.TickCount;
            }
        }
    }

    //人员进入地图
    HumanEnter(map: TEnvirnoment) {
        let item: FreshMapData = this.monGenMap.get(map.MapID);
        if (item) {
            if (item.lastClearTime > 0 || map.MonCount == 0) {
                this.freshClearMon(item)
            }
            item.lastLeaveTime = 0;
        }
    }

    //刷新怪物
    freshMon() {
        // let startTime=GameLib.TickCount;

        if (this.isFresh) {
            return;
        }

        this.isFresh = true;
        let time = GameLib.TickCount;

        for (let i = 0; i < this.monGenSet.length; i++) {
            let item: FreshMapData = this.monGenSet[i];

            let map: TEnvirnoment = GameLib.FindMap(item.mapId);
            if (!map) {
                continue;
            }

            //如果允许清理怪物 没人就不刷怪
            if (item.isClear) {
                let humCount = map.HumCount;
                if (humCount == 0) {
                    //没人且还没清理怪物 检查是否需要清理
                    if (item.lastClearTime == 0) {
                        let clearTime = item.lastLeaveTime + ClearMonTime;
                        if (clearTime < time) {
                            this.clearMon(item, map);
                        }
                    }
                    continue;
                }
            }

            // 


            for (let j = 0; j < item.monList.length; j++) {
                let mon = item.monList[j];
                let freshTime = mon.lastFreshTime + mon.interval * Minute;

                if (freshTime < time) {
                    let nowNum = map.GetMonCountEx(mon.name)
                    let count = mon.num - nowNum;

                    if (count > 0) {

                        let syNum = this.loopFresh(mon, item.mapId, count)
                        mon.lastFreshTime = time;
                        if (syNum < 0) {
                            saveLog(`${map.Name}的  ${mon.name},剩余${syNum}只`, LogType.FreshMon)
                        }

                    }
                    else if (count < 0) {
                        saveLog(`${map.Name}有${map.HumCount}人  ${mon.name}有${nowNum}只,刷新${count}只`, LogType.FreshMon)
                    }

                }
            }
        }
        this.isFresh = false;

    }

    //清理怪物
    clearMon(mapSet: FreshMapData, map: TEnvirnoment): void {
        for (let i = 0; i < ClearMonList.length; i++) {
            let name = ClearMonList[i];
            map.ClearMon(true, name);
        }
        for (let i = 0; i < mapSet.monList.length; i++) {
            let mon: FreshItem = mapSet.monList[i];
            let count: number = map.GetMonCountEx(mon.name)
            map.ClearMon(true, mon.name);
            mon.lastClearNum = count;
            if (count > 0) {
                saveLog(`地图${mapSet.mapName}清理怪物${mon.name}  ${count}只`, LogType.FreshMon)
            }
        }


        mapSet.lastLeaveTime = 0;
        mapSet.lastClearTime = GameLib.TickCount;
    }

    //刷新被清理的怪物
    freshClearMon(mapSet: FreshMapData): void {
        if (mapSet.isClear === false) {
            return
        }
        for (let i = 0; i < mapSet.monList.length; i++) {
            let mon: FreshItem = mapSet.monList[i];
            let num: number = mon.lastClearNum;

            //如果不存在清理的怪物 且很久没有刷新了 先刷1/5的怪物
            if (num == 0) {
                let freshTime = mon.lastFreshTime + mon.interval * Minute;
                if (freshTime < GameLib.TickCount) {
                    num = Math.floor(mon.num / 5);
                }
            }
            num = Math.min(num, mon.num)
            if (num > 0) {
                saveLog(`地图${mapSet.mapName}刷新清理怪物:${mon.name}count:${num}`, LogType.FreshMon)
                this.loopFresh(mon, mapSet.mapId, num);
            }

            mon.lastClearNum = 0;

        }
        mapSet.lastClearTime = 0;
    }

    loopFresh(mon: FreshItem, mapId: string, num: number) {
        return loopMongen(mapId, mon.name, mon.x, mon.y, mon.range, num)
    }

}

//循环刷怪 返回还有多少怪物没有刷完
export function loopMongen(mapId: string, monName: string, x: number, y: number, range: number, num: number, cb?: FreshMonCallBack): number {
    let count = num;
    let set = getSpecialMonManage().getSpecialMonSet(monName);

    for (let i = 0; i < loopNum; i++) {
        let list: TActorList = GameLib.MonGen(mapId, monName, count, x, y, range, CampEnum.Mon, 0, 0, false, true, false, true);
        if (list) {

            if (set) {
                const {
                    TriggerDieEvent = false,
                    TriggerAINpcExecute = false,
                    TriggerSelectMagicBeforeAttack = false
                } = set;
                for (let j = 0; j < list.Count; j++) {
                    let actor: TActor = list.Actor(j);
                    actor.TriggerDieEvent = TriggerDieEvent;
                    actor.TriggerSelectMagicBeforeAttack = TriggerSelectMagicBeforeAttack;
                    actor.TriggerAINpcExecute = TriggerAINpcExecute;

                    //怪物添加技能
                    if (set.addSkill && set.addSkill.length > 0) {
                        for (let i = 0; i < set.addSkill.length; i++) {
                            let item = set.addSkill[i];

                            let lv = 0;
                            let skillLevel = 0
                            if (item.level >= 3) {
                                skillLevel = 3;
                                lv = item.level - 3;
                            }
                            else {
                                skillLevel = item.level
                            }

                            actor.AddSkill(item.skillName, skillLevel);

                            if (lv > 0) {
                                let skill: TUserMagic = actor.FindSkill(item.skillName)
                                skill.SetStrengthen(lv)
                            }
                        }
                    }

                    //添加元素
                    if (set.addAbility && set.addAbility.length > 0) {
                        for (let i = 0; i < set.addAbility.length; i++) {
                            let item = set.addAbility[i];
                            actor.SetNVar(item.key, item.value || 0)
                        }
                    }

                    //修改基础属性 不可用
                    // if (set.baseAbility) {
                    //     let ability = set.baseAbility
                    //     if (ability.ac1) {
                    //         actor.ACMin = ability.ac1;
                    //     }
                    //     if (ability.ac2) {
                    //         actor.ACMax = ability.ac2;
                    //     }
                    //     if (ability.mac1) {
                    //         actor.MACMin = ability.mac1;
                    //     }
                    //     if (ability.mac2) {
                    //         actor.MACMax = ability.mac2;
                    //     }
                    //     if (ability.dc1) {
                    //         actor.DCMin = ability.dc1;
                    //     }
                    //     if (ability.dc2) {
                    //         actor.DCMax = ability.dc2;
                    //     }
                    //     if (ability.mc1) {
                    //         actor.MCMin = ability.mc1;
                    //     }
                    //     if (ability.mc2) {
                    //         actor.MCMax = ability.mc2;
                    //     }
                    // }


                }
            }

            count -= list.Count;
            if (cb) {
                cb(list);
            }
        }
        if (count <= 0) {
            break;
        }
    }

    return count;
}
